package com.example.jwt.annotation;

import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.io.IORuntimeException;
import com.alibaba.fastjson.JSON;
import com.example.jwt.service.JwtRoleService;
import com.example.jwt.utils.MyJwtUtil;
import com.example.jwt.utils.R;
import org.springframework.stereotype.Component;

import org.springframework.util.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.Set;

/**
 * 权限拦截器
 * 
 * @author Mason.wei
 * @time 2018年7月4日
 */
@Component
public class PermissionsInterceptor extends HandlerInterceptorAdapter {

	@Resource
	private JwtRoleService jwtRoleService;


	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		if(handler instanceof HandlerMethod) {
			HandlerMethod myHandlerMethod = (HandlerMethod) handler;
			Method method = myHandlerMethod.getMethod();
			if (method.isAnnotationPresent(MyAuthority.class)) {
				// 方法上有该注解
				MyAuthority permissionAnnotation = method.getAnnotation(MyAuthority.class);
				String[] roles = permissionAnnotation.roles();
				String[] permissions = permissionAnnotation.permissions();
				int relation = permissionAnnotation.relation();
				if(StringUtils.isEmpty(roles) && StringUtils.isEmpty(permissions)){
					return  false;
				}
				boolean is = Authentication(request, response, roles,permissions,relation);
				if(is){
					return true;
				}else {
					return false;
				}
			}
		}
		return true;
	}


	/**
	 * 鉴权
	 * @param request
	 * @param response
	 * @param roles 角色
	 * @param permissions 权限
	 * @param relation 权限相互关系 1其存 2共存
	 * @return
	 */
	public boolean Authentication(HttpServletRequest request,HttpServletResponse response,String[] roles,String[] permissions,Integer relation){
		boolean isRoles = false;
		boolean isPermission = false;

		//你从数据库中获取到的你的权限
		String username = MyJwtUtil.getUsername(request.getHeader("token"));
		//拿到用户角色
		Set<String> userRoles = jwtRoleService.findUserRoles(username);
		isRoles = isCompared(roles, userRoles);

		//拿到用户的权限
		Set<String> permissionList = jwtRoleService.findUserPermission(username);
		isPermission = isCompared(permissions, permissionList);
		//权限属于存其 还是 共存
		if( relation == 1 ? isRoles || isPermission : isRoles && isPermission){
			return true;
		}else {
			response.setStatus(HttpServletResponse.SC_OK);
			response.setContentType("application/json;charset=UTF-8");
			PrintWriter writer=null;
			try {
				writer=response.getWriter();
				writer.write(JSON.toJSONString(R.error("权限不足")));
				writer.flush();
			} catch (IOException ex) {
				throw ExceptionUtil.wrap(new IOException("未授权，操作失败！"), IORuntimeException.class);
			}finally {
				if(writer!=null) {
					writer.close();
				}
			}
			return false;
		}
	}

	/**
	 * 判断两个数组中是否存在冲突
	 * @param roles
	 * @param roleList
	 * @return
	 */
	public static boolean isCompared(String[] roles,Set<String> roleList){
		boolean save = false;
		StringBuilder str = new StringBuilder();
		for(String st : roles){
			str.append(st);
			str.append(",");
		}
		List<String> list = Arrays.asList(str.toString().trim().split(","));
		if(list.size()<1){
			return false;
		}
		for(String role:list) {
			for(String systemRole:roleList){
					if(role.equals(systemRole)){
						save=true;
						break;
					}
			}
			if(save){
				break;
			}
		}
		return save;
	}



}
